#ifndef _H_EXF_H_
#define _H_EXF_H_
#include <dtype.h>


//exf文件信息
typedef struct {
    byte flag[4];//必须为：0XDC 'E' 'X' 'F'
#   define ExfFile_Flag {0XDC, 'E', 'X', 'F'}

    uint8 type;//文件数据类型

#   define ExfFile_DataType_Invalid 0X00 //无效文件
#   define ExfFile_DataType_DlrPgm 0X20 //DLR程序文件
#   define ExfFile_DataType_UnixPgm 0X60 //Unix本地程序文件
#   define ExfFile_DataType_LinuxPgm 0X65 //Linux本地程序文件
#   define ExfFile_DataType_LinuxKerl 0X66 //Linux内核程序文件
#   define ExfFile_DataType_FreeBSDPgm 0X6A //FreeBSD本地程序文件
#   define ExfFile_DataType_DotNetIL 0X70 //.NET字节码文件
#   define ExfFile_DataType_JvmBC 0X75 //JVM字节码文件
#   define ExfFile_DataType_WindowsPgm 0X80 //Windows本地程序文件
#   define ExfFile_DataType_MacOSPgm 0X90 //macOS本地程序文件
    
    uint8 format;//格式版本（当前为0X01）
    //uint8 bsMarker;//大小端标记（0XFE 小端；0XEF 大端）
    bool isBig;//是否为大端
    uint8 bitFlag;//文件位数(0X00无效；0X16 16位结构（暂时保留）；0X32 32位结构；0X64 64位结构)
    string filePath;//文件路径
    nuint size;//文件大小
    ptr stream;//流
}ExfFileInfo;

//32位文件头
typedef struct 
{
	byte ident[8];//与设备无关的文件描述
	uint32 flag;//标志，自定义描述标志
	uint16 type;//文件类型
	uint16 machine;//体系结构
	uint16 majorVersion;//文件主版本
	uint16 minorVersion;//文件次版本

	uint32 ehoffset;//扩展头偏移
	uint16 ehsize;//扩展头大小

	uint16 shcount;//节表数量
	uint32 shoffset;//节表偏移

	uint32 dsoffset;//数据段偏移
	uint32 dssize;//数据段总大小
}Exf32_Header;

//64位文件头
typedef struct 
{
	byte ident[8];//与设备无关的文件描述
	uint32 flag;//标志，自定义描述标志
	uint16 type;//文件描述类型
	uint16 machine;//文件体系结构
	uint16 majorVersion;//文件主版本
	uint16 minorVersion;//文件次版本
	uint64 ehoffset;//扩展头偏移
	uint32 ehsize;//扩展头大小
	uint32 shcount;//节表数量
	uint64 shoffset;//节表偏移
	uint64 dsoffset;//数据段偏移
	uint64 dssize;//数据段总大小
}Exf64_Header;

//文件描述类型
#define EXF_Type_Unknown 0X00 //未知类型
#define EXF_Type_Relocate 0X01 //重定位文件
#define EXF_Type_Executable 0X02 //可执行程序
#define EXF_Type_Shared 0X03 //共享类库
#define EXF_Type_Symbol 0X04 //符号声明
#define EXF_Type_Core 0X05 //核心程序

//体系结构
#define EXF_Machine_None 0X00 //未知机器
#define EXF_Machine_DLR 0X20 //DLR
#define EXF_Machine_JVM 0X30 //JVM
#define EXF_Machine_dotNET 0X31 //dotNET
#define EXF_Machine_LuaBC 0X32 //LuaBC
#define EXF_Machine_X86 0X55 //X86
#define EXF_Machine_ARM 0X56 //ARM
#define EXF_Machine_MIPS 0X57 //MIPS
#define EXF_Machine_AVR 0X58 //AVR
#define EXF_Machine_MIPS64 0X59 //MIPS64
#define EXF_Machine_CUDA 0X5A //CUDA
#define EXF_Machine_IA64 0X5B //IA64
#define EXF_Machine_ARM64 0X5C //ARM64
#define EXF_Machine_RISCV 0X5D //RISCV
#define EXF_Machine_AVR32 0X5E //AVR32
#define EXF_Machine_X64 0X5F //X64
#define EXF_Machine_LoongArch 0X60 //LoongArch

//32位节头
typedef struct 
{
	byte name[8];//节名称
	uint16 type;//节类型，自行定义
	uint16 flag;//标志，自行定义
	uint32 vaddr;//装载后的虚拟地址
	uint32 dsoffset;//基于数据段基址的数据偏移
	uint32 dssize;//数据大小
	uint32 addin;//附加数据信息
	uint32 align;//数据对齐
}Exf32_SectionHeader;

//64位节头
typedef struct 
{
	byte name[8];//节名称
	uint16 type;//节类型，自行定义
	uint16 flag;//标志，自行定义
	uint64 vaddr;//装载后的虚拟地址
	uint64 dsoffset;//基于数据段基址的数据偏移
	uint32 dssize;//数据大小
	uint32 addin;//附加数据信息
	uint32 align;//数据对齐
}Exf64_SectionHeader;

//exf32文件写出信息
typedef struct 
{
    uint8 type;//文件数据类型
    uint8 format;//格式版本（当前为0X01）
    uint8 bsMarker;//大小端标记（0XFE 小端；0XEF 大端; 0X00由系统选择）
    uint8 bitFlag;//文件位数(0X00无效；0X16 16位结构（暂时保留）；0X32 32位结构；0X64 64位结构)
	
    uint32 ehsize;//扩展头大小
	uint32 shcount;//节表数量
    
	uint64 dssize;//数据段总大小
    union{
        Exf32_Header* header32;//文件头
        Exf64_Header* header64;//文件头
    }
    union{
        Exf32_SectionHeader* section32s;//节表
        Exf64_SectionHeader* section64s;//节表
    }
    ptr extHeader;//扩展头
    ptr data;//数据段
}ExfFileWrite;





//获取exf文件信息
ExfFileInfo* Exf_LoadInfo(string file);

//写出exf文件
bool Exf_Write(string file, ExfFileWrite write);


//获取32位exf文件头
Exf32_Header *Exf32_GetHeader(ExfFileInfo* fi);

//获取32位节头表
Exf32_SectionHeader *Exf32_GetSections(ExfFileInfo* fi, Exf32_Header* h);


//获取64位exf文件头
Exf64_Header *Exf64_GetHeader(ExfFileInfo* fi);

//获取64位节头表
Exf64_SectionHeader *Exf64_GetHeader(ExfFileInfo* fi, Exf64_Header* h);



#endif
